﻿using Common.Communication;
using Common.Tool.DataTools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Common.Device.Interfaces;
using Common.Device.DeviceDb;

namespace DianYuan.AC
{
    public class AC13003SerialPort : SerialPortBase, IDianYuan
    {
        public string Name { get; set; }
        byte Addr { get; set; } = 0x64;
        public AC13003SerialPort(UseDevice device) : base(device.port, Convert.ToInt32(device.parameter), timeout: 1500)
        {
            Name = device.name;
            Addr = Convert.ToByte(device.addr);
        }
        public Result<bool> SetOn(double vol, double cur = 0, int channel = 1)
        {
            lock (this)
            {
                var result = new Result<bool>();
                var write = new Result<byte[]>();
                var read = new Result<byte[]>();
                AppendInfo(Name, $"通道{channel}设置输出{vol}V");
                var command = CmdSetVol(vol);
                write = WriteThenRead(command, wait: 100);
                if (!write.IsSucceed || !write.Value.SequenceEqual(command))
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(100);
                command = CmdGetSetVol();
                //发送指令并返回
                read = WriteThenRead(command, wait: 100);
                if (!read.IsSucceed || !read.Value.SequenceEqual(CmdGetSetVolOk(vol)))
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"通道{channel}打开输出");
                command = CmdOutPutOn();
                write = WriteThenRead(command, wait: 100);
                if (!write.IsSucceed || !write.Value.SequenceEqual(command))
                {
                    result.IsSucceed = false;
                    result.Err = "打开输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(2000);
                command = CmdGetOutPut();
                //发送指令并返回
                read = WriteThenRead(command, wait: 100);
                if (!read.IsSucceed || !read.Value.SequenceEqual(CmdOn()))
                {
                    result.IsSucceed = false;
                    result.Err = "打开输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "设置输出成功");
                return result.EndTime();
            }
        }
        public Result<bool> SetOff(int channel = 1)
        {
            lock (this)
            {
                Result<bool> result = new Result<bool>();
                var write = new Result<byte[]>();
                var read = new Result<byte[]>();
                AppendInfo(Name, $"通道{channel}关闭输出");
                var command = CmdOutPutOff();
                write = WriteThenRead(command, wait: 100);
                if (!write.IsSucceed || !write.Value.SequenceEqual(command))
                {
                    result.IsSucceed = false;
                    result.Err = "关闭输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(2000);
                command = CmdGetOutPut();
                //发送指令并返回
                read = WriteThenRead(command, wait: 100);
                if (!read.IsSucceed || !read.Value.SequenceEqual(CmdOff()))
                {
                    result.IsSucceed = false;
                    result.Err = "关闭输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "关闭输出成功");
                return result.EndTime();
            }
        }
        public Result<double> GetVoltage(int channel = 1)
        {
            lock (this)
            {
                Result<double> result = new Result<double>();
                var write = new Result<byte[]>();
                var read = new Result<byte[]>();
                AppendInfo(Name, $"通道{channel}读取当前电压");
                var command = CmdGetVolt();
                //发送指令并返回
                read = WriteThenRead(command, wait: 100);
                if (!read.IsSucceed || read.Value.Length != 7 || !read.Value.Take(3).SequenceEqual(new byte[] { Addr, 0x03, 0x02 }))
                {
                    result.IsSucceed = false;
                    result.Err = "读取当前电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                result.Value = ((read.Value[3] << 8) + read.Value[4]) / 10.0f;
                AppendResult(Name, DataConvert.ToUnit(result.Value, "F3") + "V");
                return result.EndTime();
            }
        }
        public Result<double> GetCurrent(int channel = 1)
        {
            lock (this)
            {
                Result<double> result = new Result<double>();
                result.IsSucceed = false;
                result.Err = "暂不支持";
                return result.EndTime();
            }
        }
        public Result<double> GetPower(int channel = 1)
        {
            lock (this)
            {
                Result<double> result = new Result<double>();
                result.IsSucceed = false;
                result.Err = "暂不支持";
                return result.EndTime();
            }
        }
        byte[] CmdSetVol(double value)
        {
            int vol = Convert.ToInt32(value * 10);
            byte h = Convert.ToByte((vol >> 8) & 0xff);
            byte l = Convert.ToByte(vol & 0xff);
            byte[] data = new byte[] { Addr, 0x06, 0x00, 0x14, h, l };
            return ByteHelper.Crc16(data, data.Length, false);
        }
        byte[] CmdGetSetVol()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x00, 0x14, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, false);
        }
        byte[] CmdGetSetVolOk(double value)
        {
            int vol = Convert.ToInt32(value * 10);
            byte h = Convert.ToByte((vol >> 8) & 0xff);
            byte l = Convert.ToByte(vol & 0xff);
            byte[] data = new byte[] { Addr, 0x03, 0x02, h, l };
            return ByteHelper.Crc16(data, data.Length, false);
        }
        byte[] CmdOutPutOn()
        {
            byte[] data = new byte[] { Addr, 0x06, 0x00, 0x12, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, false);
        }
        byte[] CmdOutPutOff()
        {
            byte[] data = new byte[] { Addr, 0x06, 0x00, 0x12, 0x00, 0x00 };
            return ByteHelper.Crc16(data, data.Length, false);
        }
        byte[] CmdGetOutPut()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x00, 0x00, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, false);
        }
        byte[] CmdOn()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x02, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, false);
        }
        byte[] CmdOff()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x02, 0x00, 0x00 };
            return ByteHelper.Crc16(data, data.Length, false);
        }
        byte[] CmdGetVolt()
        {
            byte[] data = new byte[] { Addr, 0x03, 0x00, 0x02, 0x00, 0x01 };
            return ByteHelper.Crc16(data, data.Length, false);
        }
    }
}
